const { prisma } = require('../config/prisma');

/**
 * 聊天群组模型 - Prisma版本
 */
class ChatGroupPrisma {
  constructor(data) {
    this.id = data.id;
    this.group_name = data.group_name;
    this.group_avatar = data.group_avatar;
    this.description = data.description;
    this.group_type = data.group_type || 'group';
    this.private_user_ids = data.private_user_ids;
    this.created_at = data.created_at;

    // 关联数据
    this.group_members = data.group_members;
    this.messages = data.messages;
  }

  /**
   * 创建新群组
   * @param {Object} groupData 群组数据
   * @returns {Promise<ChatGroupPrisma>}
   */
  static async create(groupData) {
    const { group_name, group_avatar, description, group_type = 'group', private_user_ids } = groupData;

    const group = await prisma.chat_groups.create({
      data: {
        group_name,
        group_avatar: group_avatar || null,
        description: description || null,
        group_type,
        private_user_ids: private_user_ids || null
      }
    });

    return new ChatGroupPrisma(group);
  }

  /**
   * 根据ID查找群组
   * @param {number} id 群组ID
   * @returns {Promise<ChatGroupPrisma|null>}
   */
  static async findById(id) {
    const group = await prisma.chat_groups.findUnique({
      where: { id: parseInt(id) }
    });

    return group ? new ChatGroupPrisma(group) : null;
  }

  /**
   * 根据ID查找群组（包含成员信息）
   * @param {number} id 群组ID
   * @returns {Promise<ChatGroupPrisma|null>}
   */
  static async findByIdWithMembers(id) {
    const group = await prisma.chat_groups.findUnique({
      where: { id: parseInt(id) },
      include: {
        group_members: {
          include: {
            users: {
              select: {
                id: true,
                nickname: true,
                avatar_url: true
              }
            }
          }
        }
      }
    });

    return group ? new ChatGroupPrisma(group) : null;
  }

  /**
   * 获取所有群组列表（默认只返回群聊，排除私聊）
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getList(options = {}) {
    // 默认使用getGroupList方法，只返回群聊
    return await this.getGroupList(options);
  }

  /**
   * 获取用户所在的群组列表
   * @param {number} userId 用户ID
   * @returns {Promise<Array<ChatGroupPrisma>>}
   */
  static async getUserGroups(userId) {
    const groups = await prisma.chat_groups.findMany({
      where: {
        group_members: {
          some: {
            user_id: BigInt(userId)
          }
        }
      },
      include: {
        group_members: {
          where: {
            user_id: BigInt(userId)
          },
          select: {
            joined_at: true
          }
        }
      },
      orderBy: {
        group_members: {
          _count: 'desc'
        }
      }
    });

    return groups.map(group => new ChatGroupPrisma(group));
  }

  /**
   * 获取群组成员数量
   * @param {number} groupId 群组ID
   * @returns {Promise<number>}
   */
  static async getMemberCount(groupId) {
    return await prisma.group_members.count({
      where: { group_id: parseInt(groupId) }
    });
  }

  /**
   * 检查用户是否在群组中
   * @param {number} groupId 群组ID
   * @param {number} userId 用户ID
   * @returns {Promise<boolean>}
   */
  static async isUserInGroup(groupId, userId) {
    const member = await prisma.group_members.findFirst({
      where: {
        group_id: parseInt(groupId),
        user_id: BigInt(userId)
      }
    });
    return !!member;
  }

  /**
   * 更新群组信息
   * @param {number} id 群组ID
   * @param {Object} updateData 更新数据
   * @returns {Promise<ChatGroupPrisma|null>}
   */
  static async update(id, updateData) {
    const allowedFields = ['group_name', 'group_avatar', 'description'];
    const data = {};

    Object.keys(updateData).forEach(key => {
      if (allowedFields.includes(key)) {
        data[key] = updateData[key];
      }
    });

    if (Object.keys(data).length === 0) {
      throw new Error('没有有效的更新字段');
    }

    const group = await prisma.chat_groups.update({
      where: { id: parseInt(id) },
      data
    });

    return new ChatGroupPrisma(group);
  }

  /**
   * 删除群组
   * @param {number} id 群组ID
   * @returns {Promise<boolean>}
   */
  static async delete(id) {
    await prisma.chat_groups.delete({
      where: { id: parseInt(id) }
    });
    return true;
  }

  /**
   * 获取群组统计信息
   * @returns {Promise<Object>}
   */
  static async getStats() {
    const [total, totalMembers, totalMessages] = await Promise.all([
      prisma.chat_groups.count(),
      prisma.group_members.count(),
      prisma.messages.count()
    ]);

    const avgMembersPerGroup = total > 0 ? Math.round(totalMembers / total) : 0;

    return {
      total,
      totalMembers,
      totalMessages,
      avgMembersPerGroup
    };
  }

  /**
   * 创建或获取私聊群组
   * @param {number} userId1 用户1的ID
   * @param {number} userId2 用户2的ID
   * @returns {Promise<ChatGroupPrisma>}
   */
  static async createOrGetPrivateChat(userId1, userId2) {
    // 确保用户ID顺序一致（小的在前）
    const id1 = parseInt(userId1);
    const id2 = parseInt(userId2);
    const smallerId = Math.min(id1, id2);
    const largerId = Math.max(id1, id2);
    const privateUserIds = `${smallerId}_${largerId}`;

    // 先查找是否已存在私聊群组，包括成员信息
    const existingGroup = await prisma.chat_groups.findFirst({
      where: {
        group_type: 'private',
        private_user_ids: privateUserIds
      },
      include: {
        group_members: true
      }
    });

    if (existingGroup) {
      return new ChatGroupPrisma(existingGroup);
    }

    // 使用事务确保数据一致性
    const result = await prisma.$transaction(async (tx) => {
      // 再次检查是否存在（防止并发创建）
      const doubleCheck = await tx.chat_groups.findFirst({
        where: {
          group_type: 'private',
          private_user_ids: privateUserIds
        }
      });

      if (doubleCheck) {
        return doubleCheck;
      }

      // 创建新的私聊群组
      const groupData = {
        group_name: `私聊_${privateUserIds}`,
        group_avatar: null,
        description: '私聊会话',
        group_type: 'private',
        private_user_ids: privateUserIds
      };

      const newGroup = await tx.chat_groups.create({
        data: groupData
      });

      // 使用 try-catch 来处理重复成员的问题
      try {
        await Promise.all([
          tx.group_members.create({
            data: {
              group_id: newGroup.id,
              user_id: BigInt(smallerId),
              role: 'member'
            }
          }),
          tx.group_members.create({
            data: {
              group_id: newGroup.id,
              user_id: BigInt(largerId),
              role: 'member'
            }
          })
        ]);
      } catch (error) {
        // 如果是重复键错误，就忽略（成员已存在）
        if (error.code !== 'P2002') {
          throw error;
        }
      }

      return newGroup;
    });

    return new ChatGroupPrisma(result);
  }

  /**
   * 获取用户的私聊列表
   * @param {number} userId 用户ID
   * @returns {Promise<Array<Object>>}
   */
  static async getUserPrivateChats(userId) {
    const privateChats = await prisma.chat_groups.findMany({
      where: {
        group_type: 'private',
        group_members: {
          some: {
            user_id: BigInt(userId)
          }
        }
      },
      include: {
        group_members: {
          include: {
            users: {
              select: {
                id: true,
                nickname: true,
                avatar_url: true
              }
            }
          }
        },
        messages: {
          orderBy: {
            created_at: 'desc'
          },
          take: 1,
          select: {
            content: true,
            created_at: true
          }
        }
      },
      orderBy: {
        created_at: 'desc'
      }
    });

    return privateChats.map(chat => {
      // 找到对方用户信息
      const otherUser = chat.group_members.find(member =>
        member.user_id.toString() !== userId.toString()
      );

      return {
        id: chat.id.toString(),
        group_name: chat.group_name,
        group_type: chat.group_type,
        other_user: otherUser ? {
          id: otherUser.user_id.toString(),
          nickname: otherUser.users.nickname,
          avatar_url: otherUser.users.avatar_url
        } : null,
        last_message: chat.messages[0]?.content || null,
        last_message_time: chat.messages[0]?.created_at || null,
        created_at: chat.created_at
      };
    });
  }

  /**
   * 获取群聊列表（排除私聊）
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getGroupList(options = {}) {
    const { page = 1, pageSize = 20, search } = options;
    const pageNum = parseInt(page);
    const pageSizeNum = parseInt(pageSize);
    const skip = (pageNum - 1) * pageSizeNum;

    // 构建查询条件（只查询群聊，排除私聊）
    const where = {
      group_type: 'group'
    };

    if (search && search.trim()) {
      where.OR = [
        { group_name: { contains: search.trim() } },
        { description: { contains: search.trim() } }
      ];
    }

    // 并行查询总数和列表数据
    const [total, groups] = await Promise.all([
      prisma.chat_groups.count({ where }),
      prisma.chat_groups.findMany({
        where,
        include: {
          group_members: {
            select: { id: true }
          }
        },
        orderBy: { created_at: 'desc' },
        skip,
        take: pageSizeNum
      })
    ]);

    return {
      data: groups.map(group => {
        const groupInstance = new ChatGroupPrisma(group);
        // 添加成员数量
        groupInstance.member_count = group.group_members.length;
        return groupInstance;
      }),
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total,
        totalPages: Math.ceil(total / pageSizeNum)
      }
    };
  }

  /**
   * 转换为JSON对象
   * @returns {Object}
   */
  toJSON() {
    const result = {
      id: this.id.toString(),
      group_name: this.group_name,
      group_avatar: this.group_avatar,
      description: this.description,
      group_type: this.group_type,
      private_user_ids: this.private_user_ids,
      created_at: this.created_at
    };

    // 如果有关联数据，也包含进来
    if (this.group_members) {
      result.member_count = this.group_members.length;
      result.members = this.group_members.map(member => ({
        user_id: member.user_id ? member.user_id.toString() : '',
        joined_at: member.joined_at,
        ...(member.users && {
          nickname: member.users.nickname,
          avatar_url: member.users.avatar_url
        })
      }));
    }

    // 如果有member_count属性（从getList方法添加的），也包含进来
    if (this.member_count !== undefined) {
      result.member_count = this.member_count;
    }

    return result;
  }
}

module.exports = ChatGroupPrisma;
